﻿#pragma once
#ifndef WROBJREF_H
#define WROBJREF_H

//表示对象引用。
template <class T> class WRObjRef
{
    template <class Ty> friend class WRObjRef;

private:
    //当前指针。
    T* m_p;

public:
    //构造函数。
    inline WRObjRef(void) : m_p(0)
    {
        //add code here
    }

    //构造函数。
    inline WRObjRef(T* p) : m_p(p)
    {
        if (m_p)
        {
            m_p->addRef();
        }
    }
    //重载赋值操作符。
    inline WRObjRef& operator=(T* p)
    {
        if (m_p) m_p->release();
        m_p = p;
        if (m_p) m_p->addRef();
    }

    //构造函数。
    template <class Ty>
    inline WRObjRef(Ty* p) : m_p(static_cast<T*>(p))
    {
        if (m_p)
        {
            m_p->addRef();
        }
    }
    //重载赋值操作符。
    template <class Ty>
    inline WRObjRef& operator=(Ty* p)
    {
        if (m_p) m_p->release();
        m_p = static_cast<T*>(p);
        if (m_p) m_p->addRef();
    }

    //构造函数。
    inline WRObjRef(const WRObjRef& other) : m_p(other.m_p)
    {
        if (m_p)
        {
            m_p->addRef();
        }
    }
    //重载赋值操作符。
    inline WRObjRef& operator=(const WRObjRef& other)
    {
        if (this != &other)
        {
            if (m_p) m_p->release();
            m_p = other.m_p;
            if (m_p) m_p->addRef();
        }
        return *this;
    }

    //构造函数。
    template <class Ty>
    inline WRObjRef(const WRObjRef<Ty>& other) : m_p(static_cast<T*>(other.m_p))
    {
        if (m_p)
        {
            m_p->addRef();
        }
    }
    //重载赋值操作符。
    template <class Ty>
    inline WRObjRef& operator=(const WRObjRef<Ty>& other)
    {
        if (this != &other)
        {
            if (m_p) m_p->release();
            m_p = static_cast<T*>(other.m_p);
            if (m_p) m_p->addRef();
        }
        return *this;
    }

#ifdef Q_COMPILER_RVALUE_REFS
    //构造函数。
    inline WRObjRef(WRObjRef&& other) : m_p(other.m_p)
    {
        other.m_p = 0;
    }
    //重载赋值操作符。
    inline WRObjRef& operator=(WRObjRef&& other)
    {
        if (this != &other)
        {
            if (m_p) m_p->release();
            m_p = other.m_p;
            other.m_p = 0;
        }
        return *this;
    }
    //构造函数。
    template <class Ty>
    inline WRObjRef(WRObjRef<Ty>&& other) : m_p(static_cast<T*>(other.m_p))
    {
        other.m_p = 0;
    }
    //重载赋值操作符。
    template <class Ty>
    inline WRObjRef& operator=(WRObjRef<Ty>&& other)
    {
        if (this != &other)
        {
            if (m_p) m_p->release();
            m_p = static_cast<T*>(other.m_p);
            other.m_p = 0;
        }
        return *this;
    }
#endif

    //创建对象实例。
    inline static WRObjRef create(void)
    {
        WRObjRef v;
        v.m_p = new T();
        return v;
    }
    //创建对象实例。
    template <class TArg>
    inline static WRObjRef create(TArg arg)
    {
        WRObjRef v;
        v.m_p = new T(arg);
        return v;
    }
    //创建对象实例。
    template <class TArg1, class TArg2>
    inline static WRObjRef create(TArg1 arg1, TArg2 arg2)
    {
        WRObjRef v;
        v.m_p = new T(arg1, arg2);
        return v;
    }
    //创建对象实例。
    template <class TArg1, class TArg2, class TArg3>
    inline static WRObjRef create(TArg1 arg1, TArg2 arg2, TArg3 arg3)
    {
        WRObjRef v;
        v.m_p = new T(arg1, arg2, arg3);
        return v;
    }
    //创建对象实例。
    template <class TArg1, class TArg2, class TArg3, class TArg4>
    inline static WRObjRef create(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
    {
        WRObjRef v;
        v.m_p = new T(arg1, arg2, arg3, arg4);
        return v;
    }

    //析构函数。
    inline ~WRObjRef(void)
    {
        if (m_p) m_p->release();
    }

    //判断是否为NULL。
    inline bool null(void) const
    {
        return m_p;
    }
    //重载bool隐式转换操作符，如果引用指针为NULL，则返回False，否则返回True。
    inline operator bool(void) const
    {
        return m_p;
    }

    //交换引用。
    inline void swap(WRObjRef& other)
    {
        T* p = m_p;
        m_p = other.m_p;
        other.m_p = p;
    }
    //清除引用。
    inline void reset(void)
    {
        if (m_p)
        {
            m_p->release();
            m_p = 0;
        }
    }

    //重载等于操作符。
    inline bool operator==(const WRObjRef& other) const
    {
        return m_p == other.m_p;
    }
    //重载不等于操作符。
    inline bool operator!=(const WRObjRef& other) const
    {
        return m_p != other.m_p;
    }

    //重载等于操作符。
    template <class Ty>
    inline bool operator==(const WRObjRef<Ty>& other) const
    {
        return m_p == static_cast<T*>(other.m_p);
    }
    //重载不等于操作符。
    template <class Ty>
    inline bool operator!=(const WRObjRef<Ty>& other) const
    {
        return m_p != static_cast<T*>(other.m_p);
    }

    //重载解引用操作符。
    inline T& operator*(void) const
    {
        return *m_p;
    }
    //重载选取操作符。
    inline T* operator->(void) const
    {
        return m_p;
    }
};

#endif // WROBJREF_H
